----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    12:06:17 03/24/2011 
-- Design Name: 
-- Module Name:    mux_five - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity mux_five is
    Port ( ret_from_interrupt : in  STD_LOGIC_VECTOR (9 downto 0);
			  ret_from_sub       : in  STD_LOGIC_VECTOR (9 downto 0);
	        is_interrupt       : in  STD_LOGIC; --interrupcion proveniente del reg_int que debe ejecutarse
			  is_branch          : in  STD_LOGIC; --salto incondicional
			  is_reti            : in  STD_LOGIC; -- retorno de interrupcion
			  is_ret             : in  STD_LOGIC; -- retorno de subrutina
			  is_jump            : in  STD_LOGIC; -- salto condicional
			  mux_sum_in         : in  STD_LOGIC_VECTOR (9 downto 0); -- puede ser (pc + offset) o pc incr + 1 
           instr_reg_out      : in  STD_LOGIC_VECTOR (17 downto 0); 
           interrupt          : in  STD_LOGIC; --interrupcion en curso
           next_pc_adress     : out STD_LOGIC_VECTOR (9 downto 0)); 
end mux_five;

architecture Behavioral of mux_five is
alias jump_address : STD_LOGIC_VECTOR (9 downto 0) is instr_reg_out (9 downto 0);
	
	begin
	mux_five : process (ret_from_interrupt, ret_from_sub, is_interrupt, is_branch, is_reti, is_ret, is_jump, mux_sum_in, instr_reg_out, interrupt)
		begin
		if is_interrupt = '1' AND not interrupt = '1' then --se ejecuta una interrupcion y el reg_int esta habilitado
			next_pc_adress <= (others => '0');
		elsif is_branch = '1' then
			next_pc_adress <= mux_sum_in;
		elsif is_jump = '1'   then --jump
			next_pc_adress <= jump_address;
		elsif is_reti = '1'   then
			next_pc_adress <= ret_from_interrupt;
		elsif is_ret = '1'    then
			next_pc_adress <= ret_from_sub;
		else
			next_pc_adress <= mux_sum_in;
		end if;
	end process;
end Behavioral;

